"""
生成器和迭代器
"""


def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a


def fib2(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
        yield a


class Fib3:

    def __init__(self, n):
        self.n = n
        self.a, self.b = 0, 1
        self.idx = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.idx < self.n:
            self.a, self.b = self.b, self.a + self.b
            self.idx += 1
            return self.a
        raise StopIteration()


def main():
    fib3 = Fib3(20)
    print(tuple(fib3))
    print('-' * 50)
    for val in fib3:
        print(val)
    print('-' * 50)
    print(fib)
    print(fib(20))
    gen = fib2(20)
    print(gen)
    for val in gen:
        print(val)
    gen2 = (x ** 3 for x in range(1, 11))
    print(gen2)
    for val in gen2:
        print(val)


if __name__ == '__main__':
    main()
